#include "wl_semaphore.h"

#include "wl_trace.h"

#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
#elif defined(WL_OS_QUECTEL)
#    include "ql_rtos.h"
#else  // default linux
#    include <errno.h>
#    include <fcntl.h>
#    include <pthread.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

wl_int32 wl_semaphore_create(const wl_char* name, OUT WL_SEMAPHORE* semaphore, wl_uint32 init_count) {
    if (wl_null != semaphore) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        *semaphore = SCI_CreateSemaphore(name, init_count);
        if (wl_null == *semaphore) {
            WLLOGW("SCI_CreateSemaphore fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_semaphore_create(semaphore, init_count);
#else  // default linux
        UNUSED(name);
        sem_unlink(name);
        *semaphore = sem_open(name, O_CREAT, 0, init_count);
        if (wl_null == *semaphore) {
            WLLOGW("sem_open fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

wl_int32 wl_semaphore_wait(WL_SEMAPHORE* semaphore) {
    if (wl_null != semaphore) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_GetSemaphore(*semaphore, SCI_WAIT_FOREVER)) {
            WLLOGW("SCI_GetSemaphore fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_semaphore_wait(*semaphore, QL_WAIT_FOREVER);
#else
        if (0 != sem_wait(*semaphore)) {
            WLLOGW("sem_wait fail");
            return -1;
        }
#endif
        return 0;
    }

    return -1;
}

wl_int32 wl_semaphore_try_wait(WL_SEMAPHORE* semaphore, wl_uint32 timeout) {
    if (wl_null != semaphore) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_GetSemaphore(*semaphore, timeout)) {
            WLLOGW("SCI_GetSemaphore fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_semaphore_wait(*semaphore, timeout);
#else
        UNUSED(timeout);
        if (0 != sem_trywait(*semaphore)) {
            WLLOGW("sem_wait fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

wl_int32 wl_semaphore_post(WL_SEMAPHORE* semaphore) {
    if (wl_null != semaphore) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_PutSemaphore(*semaphore)) {
            WLLOGW("SCI_PutSemaphore fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_semaphore_release(*semaphore);
#else
        if (0 != sem_post(*semaphore)) {
            WLLOGW("sem_post fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

wl_int32 wl_semaphore_delete(WL_SEMAPHORE* semaphore) {
    if (wl_null != semaphore) {
#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
        if (SCI_SUCCESS != SCI_DeleteSemaphore(*semaphore)) {
            WLLOGW("SCI_PutSemaphore fail");
            return -1;
        }
#elif defined(WL_OS_QUECTEL)
        return ql_rtos_semaphore_delete(*semaphore);
#else
        if (0 != sem_close(*semaphore)) {
            WLLOGW("sem_destroy fail");
            return -1;
        }
#endif
        return 0;
    }
    return -1;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
